
#include <iostream>
#include <cstdio>
#include "Thread.h"
#include "RingQueue.h"
#include <unistd.h>

pthread_mutex_t gmutex = PTHREAD_MUTEX_INITIALIZER;

const char *BottleTypeStr[] = {
    "求爱瓶", "交友瓶", "求助瓶", "秘密瓶", "笑话瓶"};
const char *BottleMesStr[] = {
    "好想谈恋爱,不知花落谁家",
    "寻找志同道合的朋友",
    "急需帮助,请联系我",
    "我有一个秘密要告诉你",
    "为什么程序员总分不清万圣节和圣诞节?因为Oct31==Dec25 #"};

// 生产者函数 - 投放漂流瓶
void Producer(zmh::ring_queue<std::string> &rq, std::string name)
{
    srand(time(nullptr) + name[0]); // 根据线程名初始化随机种子

    int cnt = 0;
    while (true)
    {
        // 随机生成不同类型的漂流瓶
        int BottleType = rand() % sizeof(BottleTypeStr) / sizeof(BottleTypeStr[0]);

        char buffer[1024];
        snprintf(buffer, sizeof(buffer),
                 "[%s] 投放了第%d个%s: 内容-%s",
                 name.c_str(), ++cnt, BottleTypeStr[BottleType], BottleMesStr[BottleType]);

        // 生产漂流瓶
        rq.producer(buffer);

        // Debug
        pthread_mutex_lock(&gmutex);
        std::cout << buffer << std::endl;
        pthread_mutex_unlock(&gmutex);

        // 随机休眠0.5-1.5秒，模拟不规律投放
        usleep(500000 + rand() % 1000000);
    }
}

// 消费者函数 - 捡拾漂流瓶
void Consumer(zmh::ring_queue<std::string> &rq, std::string name)
{
    srand(time(nullptr) + name[0]); // 根据线程名初始化随机种子

    int cnt = 0;
    while (true)
    {
        // 消费漂流瓶
        std::string bottle = rq.consumer();

        // 输出消费信息
        pthread_mutex_lock(&gmutex);
        printf("[%s] 捡到了第%d个漂流瓶: %s\n",
               name.c_str(), ++cnt, bottle.c_str());
        pthread_mutex_unlock(&gmutex);

        // 随机处理时间0.3-3秒，模拟不同类型的处理时间
        usleep(300000 + rand() % 2700000);
    }
}

int main()
{
    zmh::ring_queue<std::string> rq(10);

    zmh::Thread p1(Producer, std::ref(rq), "无感");
    zmh::Thread p2(Producer, std::ref(rq), "常梦圆");
    zmh::Thread p3(Producer, std::ref(rq), "李阳");

    zmh::Thread c1(Consumer, std::ref(rq), "庄梦涵");
    zmh::Thread c2(Consumer, std::ref(rq), "郭怡文");
    zmh::Thread c3(Consumer, std::ref(rq), "董高洁");
    zmh::Thread c4(Consumer, std::ref(rq), "刘爽");
    zmh::Thread c5(Consumer, std::ref(rq), "孟子义");

    p1.join();
    p2.join();
    p3.join();
    c1.join();
    c2.join();
    c3.join();
    c4.join();
    c5.join();

    return 0;
}